package cron

import (
	"errors"
	"sync"
	"time"
)


type TaskFunc  func()

type eTaskStatus int
const (
	_ eTaskStatus = iota
	taskStatusInit
	taskStatusWaitStart
	taskStatusRunning
	taskStatusWaitStop
	taskStatusStop
)

var (
	taskErrAlreadyRunning = errors.New("Cron task already running\n")

)

type cronTask struct {
	duration time.Duration	  //定时间隔
	f	TaskFunc			  //处理函数

	name string 			  //任务名称
	status 		eTaskStatus           //任务运行状态
	chanClose   chan int      //关闭控制
}

func newCronTask(name string, duration time.Duration, f TaskFunc) *cronTask {
	t := &cronTask{
		duration:  duration,
		f:         f,
		status:    taskStatusInit,
		chanClose: nil,
		name: name,
	}

	return t
}

func (t *cronTask) Start(wbTask *sync.WaitGroup) error{
	var err error

	switch t.status {
	case taskStatusInit, taskStatusStop:
		t.status = taskStatusWaitStart
		t.chanClose = make(chan int)
		go t.run(wbTask)
	case taskStatusRunning:
		err = taskErrAlreadyRunning
	default:
		err = errors.New("Unexpected status on start\n")
	}
	return err
}

func (t *cronTask) Stop() error{

	var err error

	switch t.status {
	case taskStatusRunning:
		t.status = taskStatusWaitStop //等待停止状态
		t.chanClose <- 1
	default:
		err = errors.New("Unexpected status on Stop\n")
	}
	return err

}

func (t *cronTask) run(wbTask *sync.WaitGroup){

	t1 := time.NewTimer(t.duration)

	wbTask.Add(1)
	defer wbTask.Done()

	quit := false
	t.status = taskStatusRunning
	for {
		if quit {
			break
		}
		select {
		case <-t1.C:
			if nil != t.f {
				t.f()
			}
			//执行完成再重新定时
			t1.Reset(t.duration)
		case <-t.chanClose:
			quit = true
			break
		}
	}

	close(t.chanClose)
	//执行完成设备结束状态
	t.status = taskStatusStop
}